package com.pig.graduate.service.impl.material;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.pig.graduate.common.exception.MyException;
import com.pig.graduate.domain.material.MaterialDeliver;
import com.pig.graduate.domain.material.MaterialInventory;
import com.pig.graduate.domain.material.MaterialStorage;
import com.pig.graduate.domain.sys.SysUser;
import com.pig.graduate.mapper.material.MaterialInventoryMapper;
import com.pig.graduate.mapper.material.MaterialStorageMapper;
import com.pig.graduate.mapper.sys.SysUserMapper;
import com.pig.graduate.result.MyResult;
import com.pig.graduate.service.material.MaterialDeliverService;
import com.pig.graduate.mapper.material.MaterialDeliverMapper;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* @author 星星眼
* @description 针对表【material_deliver(物料出库)】的数据库操作Service实现
* @createDate 2023-04-01 22:27:32
*/
@Service
public class MaterialDeliverServiceImpl extends ServiceImpl<MaterialDeliverMapper, MaterialDeliver>
    implements MaterialDeliverService{

    @Autowired
    private MaterialDeliverMapper materialDeliverMapper;

    @Autowired
    private MaterialStorageMapper materialStorageMapper;

    @Autowired
    private MaterialInventoryMapper materialInventoryMapper;

    @Autowired
    private SqlSessionFactory sqlSessionFactory;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Override
    public MyResult deliverList(MaterialDeliver materialDeliver) {
        PageHelper.startPage(materialDeliver.getPageNum(),materialDeliver.getPageSize());
        List<MaterialDeliver> list = materialDeliverMapper.deliverList(materialDeliver);
        PageInfo<MaterialDeliver> pageInfo = new PageInfo<>(list);
        return MyResult.success(pageInfo);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public MyResult deliverMaterial(MaterialDeliver materialDeliver) {
        //该物料的所有入库记录
        List<MaterialStorage> list = materialStorageMapper.selectList(new QueryWrapper<MaterialStorage>()
                .eq("material_id",materialDeliver.getMaterialId()).orderByAsc("date_of_manufacture"));
        //扣减库存数量
        MaterialInventory materialInventory = materialInventoryMapper.selectOne(new QueryWrapper<MaterialInventory>().eq("material_id",materialDeliver.getMaterialId()));
        if(materialInventory == null){
            throw new MyException("库存中未找到出库物料");
        }
        if (materialInventory.getInventoryNumber() < materialDeliver.getDeliverNumber()){
            throw new MyException("出库数量大于库存数");
        }else if(materialInventory.getInventoryNumber() == materialDeliver.getDeliverNumber()){
            for (MaterialStorage materialStorage : list) {
                materialDeliver.setBatchPrice(materialStorage.getBatchPrice());
                materialDeliver.setBatchNumber(materialStorage.getBatchNumber());
                materialDeliver.setTotalPrice(materialStorage.getBatchPrice().multiply(new BigDecimal(materialDeliver.getDeliverNumber())));
                Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
                if (!(authentication instanceof AnonymousAuthenticationToken)) {
                    String currentUserName = authentication.getName();
                    SysUser sysUser = sysUserMapper.selectOne(new QueryWrapper<SysUser>().eq("username", currentUserName));
                    materialDeliver.setOperatorsUser(sysUser.getId());
                }
                materialDeliver.setDeliverNumber(materialStorage.getSdNumber());
                materialDeliverMapper.insert(materialDeliver);
            }
            materialInventoryMapper.deleteById(materialInventory.getId());
        }else{ //出库数量 小于库存数量
            int number = materialDeliver.getDeliverNumber();
            BigDecimal totalPrice = new BigDecimal(0);

            SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH,false);
            MaterialStorageMapper materialStorageMapper = sqlSession.getMapper(MaterialStorageMapper.class);

            for (MaterialStorage materialStorage : list) {
                materialDeliver.setBatchPrice(materialStorage.getBatchPrice());
                materialDeliver.setBatchNumber(materialStorage.getBatchNumber());
                materialDeliver.setTotalPrice(materialStorage.getBatchPrice().multiply(new BigDecimal(materialDeliver.getDeliverNumber())));
                Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
                if (!(authentication instanceof AnonymousAuthenticationToken)) {
                    String currentUserName = authentication.getName();
                    SysUser sysUser = sysUserMapper.selectOne(new QueryWrapper<SysUser>().eq("username",currentUserName));
                    materialDeliver.setOperatorsUser(sysUser.getId());
                }
                materialDeliver.setDeliverNumber(materialStorage.getStorageNumber());
                if(number > materialStorage.getStorageNumber()){
                    number -= materialStorage.getStorageNumber();
                    totalPrice = totalPrice.add(materialStorage.getTotalPrice());
                    materialDeliverMapper.insert(materialDeliver);
                }else if (number < materialStorage.getStorageNumber()){
                    materialStorage.setSdNumber(materialStorage.getStorageNumber() - number);
                    totalPrice = totalPrice.add(materialStorage.getBatchPrice().multiply(new BigDecimal(number)));
                    materialDeliver.setDeliverNumber(number);
                    materialStorageMapper.updateById(materialStorage);
                    materialDeliverMapper.insert(materialDeliver);
                    break;
                }else if(number == materialStorage.getStorageNumber()){
                    totalPrice = totalPrice.add(materialStorage.getTotalPrice());
                    materialDeliver.setDeliverNumber(number);
                    materialStorage.setSdNumber(materialStorage.getStorageNumber() - number);
                    materialStorageMapper.updateById(materialStorage);
                    materialDeliverMapper.insert(materialDeliver);
                    break;
                }
            }
            materialInventory.setInventoryNumber(materialInventory.getInventoryNumber() - materialDeliver.getDeliverNumber());
            materialInventory.setTotalPrice(materialInventory.getTotalPrice().subtract(totalPrice));
            materialInventoryMapper.updateById(materialInventory);
            sqlSession.commit();
            sqlSession.clearCache();
        }
        return MyResult.success("出库成功");
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public MyResult materialScrap(Long id) {
        MaterialStorage materialStorage = materialStorageMapper.selectById(id);
        materialStorage.setState(3); // 已报废
        materialStorageMapper.updateById(materialStorage);
        MaterialDeliver materialDeliver = new MaterialDeliver();
        materialDeliver.setDeliverType("报废出库");
        materialDeliver.setDeliverDate(new Date());
        materialDeliver.setDeliverNumber(materialStorage.getSdNumber());
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (!(authentication instanceof AnonymousAuthenticationToken)) {
            String currentUserName = authentication.getName();
            SysUser sysUser = sysUserMapper.selectOne(new QueryWrapper<SysUser>().eq("username",currentUserName));
            materialDeliver.setCollectingUser(sysUser.getId());
        }
        materialDeliver.setMaterialId(materialStorage.getMaterialId());
        materialDeliverMapper.insert(materialDeliver);
        return MyResult.success("报废成功");
    }
}




